<!--
 * @Descripttion: damage报损报溢新增
 * @version:
 * @Author: cxguo
 * @Date: 2019-08-17 20:26:23
 * @LastEditors: cxguo
 * @LastEditTime: 2020-07-23 11:14:02
 -->
<template>
  <div>
    <!-- permissionDataWithRole: {{ permissionDataWithRole }} -->
    <vxe-grid
      ref="table"
      class="grid"
      border
      resizable
      :span-method="rowspanMethod"
      highlight-hover-row
      :loading="loading"
      :columns="columnsData"
      :data="tableData"
    />
  </div>
</template>

<script>
import { oftenuse } from '@/libs/mixins'
import { listAllData } from '@/api/sys/permission.js'
import XEUtils from 'xe-utils'
import clonedeep from 'clonedeep'

export default {
  name: 'PermissionTree',
  mixins: [oftenuse],
  props: {
    permissionDataWithRole: {
      type: Array,
      default: () => { return [] }
    }
  },
  data() {
    return {
      permissionData: [],
      loading: false,
      tableData: [],
      columnsData: [
        { field: 'name1', title: '功能大类', width: 140,
          slots: {
            default: (params) => {
              const { row } = params
              const { name1 } = row
              const pdata = this.permissionData
              const children1 = pdata.filter(item => { return item.parentId === row.id1 }) || []
              const checkInfo1 = this.getCheckInfo1(pdata, children1, this.checkPermissions)
              const data = {
                props: { indeterminate: checkInfo1.indeterminate },
                model: {
                  value: checkInfo1.check,
                  callback(value) {
                    XEUtils.set(row, 'check1', value)
                  }
                },
                on: {
                  'change': (val) => {
                    this.onName1Change(val, row)
                  }
                }
              }
              return [<el-checkbox {...data}>{name1}</el-checkbox>]
            }
          }
        },
        { field: 'name2', title: '二级分类', width: 140,
          slots: {
            default: (params) => {
              const { row } = params
              const { name2 } = row
              const data = {
                props: { indeterminate: row.indeterminate2 },
                model: {
                  value: XEUtils.get(row, 'check2'),
                  callback(value) {
                    XEUtils.set(row, 'check2', value)
                  }
                },
                on: {
                  'change': (val) => {
                    this.onName2Change(val, row)
                  }
                }
              }
              return [<el-checkbox {...data}>{name2}</el-checkbox>]
            }
          }
        },
        { field: 'name3', title: '详细配置', width: 600,
          slots: {
            default: ({ row }) => {
              const { children } = row
              if (!children) return []
              const els = children.map(item => {
                const data = {
                  props: {},
                  model: {
                    value: XEUtils.get(item, 'check'),
                    callback(value) {
                      XEUtils.set(item, 'check', value)
                    }
                  },
                  on: {
                    'change': (val) => {
                      const rolePerIds = this.permissionDataWithRole.map(item => { return item.perId })
                      const perId = item.id
                      const index = rolePerIds.indexOf(perId)
                      if (index === -1) {
                        this.permissionDataWithRole.push({ perId })
                      } else {
                        this.permissionDataWithRole.splice(index, 1)
                      }
                      //
                      const data = this.permissionData
                      const children2 = data.filter(item => { return item.parentId === row.id2 })
                      const checkInfo2 = this.getCheckInfo2(data, children2, this.checkPermissions)
                      this.$set(row, 'indeterminate2', checkInfo2.indeterminate)
                      this.$set(row, 'check2', checkInfo2.check)
                    }
                  }
                }
                return <el-checkbox {...data}>{item.name}</el-checkbox>
              })
              return [els]
            }
          }
        }
      ]
    }
  },
  computed: {
    'checkPermissions': function() {
      const tableData = this.tableData
      const result = []
      tableData.forEach(item => {
        const children = item.children
        children.forEach(m => {
          if (m.check) {
            result.push({ perId: m.id })
          }
        })
      })
      return result
    }
  },
  created() {
    this.initData()
  },
  methods: {
    /**
     * 获取选中的Nodes
     */
    getCheckedNodes() {
      const tableData = this.tableData
      const result = []
      tableData.forEach(item => {
        const children = item.children || []
        children.forEach(item => {
          if (item.check) {
            result.push(item)
          }
        })
      })
      return result
    },
    // API
    listPermissionAllData() {
      this.loading = true
      return listAllData().then(res => {
        this.loading = false
        let data = res.data.data
        data = data.map(item => {
          return {
            id: item.perId,
            name: item.perName,
            parentId: item.perParent
          }
        })
        if (res.data.flag) {
          this.permissionData = clonedeep(data)
          this.tableData = this.toArrayTree(data)
        }
      })
    },
    initData() {
      this.listPermissionAllData()
    },
    /**
     * 通过数量去对比是都全部选中
     */
    toArrayTree(data) {
      const parentNode = data.filter(item => { return item.parentId === '0' })
      const list = []
      parentNode.forEach(item1 => {
        const children1 = data.filter(item => { return item.parentId === item1.id })
        const { indeterminate, check } = this.getCheckInfo1(data, children1, this.permissionDataWithRole)
        item1.indeterminate = indeterminate
        item1.check = check
        children1.forEach(item2 => {
          const children2 = data.filter(item => { return item.parentId === item2.id })
          const { indeterminate, check } = this.getCheckInfo2(data, children2, this.permissionDataWithRole)
          item2.indeterminate = indeterminate
          item2.check = check
          const rolePerIds = this.permissionDataWithRole.map(item => { return item.perId })
          children2.forEach(item => {
            if (rolePerIds.indexOf(item.id) === -1) {
              item.check = false
            } else {
              item.check = true
            }
          })
          const obj = {
            check1: item1.check,
            check2: item2.check,
            indeterminate1: item1.indeterminate,
            indeterminate2: item2.indeterminate,
            id1: item1.id,
            id2: item2.id,
            name1: item1.name,
            name2: item2.name,
            children: children2
          }
          list.push(obj)
        })
      })
      return list
    },
    getCheckInfo1(data, children, checkPermissions) {
      const result = { indeterminate: false, check: false }
      const childrensAll = []
      children.forEach(item => {
        const c2 = data.filter(m => { return m.parentId === item.id }) || []
        const c2Ids = c2.map(n => { return n.id })
        childrensAll.push(...c2Ids)
      })
      const rolePerIds = checkPermissions.map(item => { return item.perId })
      const haspers = rolePerIds.filter(item => { return childrensAll.indexOf(item) !== -1 }) || []
      if (haspers.length > 0 && haspers.length < childrensAll.length) {
        result.indeterminate = true
      } else {
        result.indeterminate = false
      }
      if (haspers.length === childrensAll.length) {
        result.check = true
      } else {
        result.check = false
      }
      return result
    },
    getCheckInfo2(data, children, checkPermissions) {
      const result = { indeterminate: false, check: false }
      const childrensAll = []
      const c2 = children || []
      const c2Ids = c2.map(n => { return n.id })
      childrensAll.push(...c2Ids)
      const rolePerIds = checkPermissions.map(item => { return item.perId })
      const haspers = rolePerIds.filter(item => { return childrensAll.indexOf(item) !== -1 }) || []
      if (haspers.length > 0 && haspers.length < childrensAll.length) {
        result.indeterminate = true
      } else {
        result.indeterminate = false
      }
      if (haspers.length === childrensAll.length) {
        result.check = true
      } else {
        result.check = false
      }
      return result
    },
    // 通用行合并函数（将相同多列数据合并为一行）
    rowspanMethod({ row, $rowIndex, column, data }) {
      const fields = ['name1', 'name2', 'name3']
      const cellValue = XEUtils.get(row, column.property)
      if (cellValue && fields.includes(column.property)) {
        const prevRow = data[$rowIndex - 1]
        let nextRow = data[$rowIndex + 1]
        if (prevRow && XEUtils.get(prevRow, column.property) === cellValue) {
          return { rowspan: 0, colspan: 0 }
        } else {
          let countRowspan = 1
          while (nextRow && XEUtils.get(nextRow, column.property) === cellValue) {
            nextRow = data[++countRowspan + $rowIndex]
          }
          if (countRowspan > 1) {
            return { rowspan: countRowspan, colspan: 1 }
          }
        }
      }
    },
    onName1Change(val, row) {
      const value = row['id1']
      const tableData = this.tableData
      const id2s = tableData.filter(item => { return item.id1 === value })
      id2s.forEach(item => {
        this.$set(item, 'check2', val)
        this.onName2Change(val, item)
      })
      this.$set(row, 'indeterminate1', false)
    },
    onName2Change(val, row) {
      const children = row.children
      children.forEach(item => {
        item.check = val
      })
      this.$set(row, 'indeterminate2', false)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
